import React, { useState } from 'react';
import { useDiaryStore } from '../../store/diaryStore';
import { useChartContext } from '../../contexts/ChartContext';

interface HeatmapCalendarProps {
  months?: number;
}

interface DayData {
  date: string;
  count: number;
  level: number;
  entries: any[];
}

const HeatmapCalendar: React.FC<HeatmapCalendarProps> = ({ months = 12 }) => {
  const entries = useDiaryStore((state) => state.entries);
  const { setFilters } = useChartContext();
  const [hoveredDay, setHoveredDay] = useState<DayData | null>(null);
  const [selectedDay, setSelectedDay] = useState<DayData | null>(null);

  // Generate calendar data
  const generateCalendarData = (): DayData[] => {
    const now = new Date();
    const startDate = new Date(now.getFullYear(), now.getMonth() - months + 1, 1);
    const endDate = new Date(now.getFullYear(), now.getMonth() + 1, 0);
    
    const days: DayData[] = [];
    const entryMap = new Map<string, any[]>();
    
    // Group entries by date
    entries.forEach(entry => {
      const dateKey = entry.date.split('T')[0];
      if (!entryMap.has(dateKey)) {
        entryMap.set(dateKey, []);
      }
      entryMap.get(dateKey)!.push(entry);
    });
    
    // Generate all days in range
    const currentDate = new Date(startDate);
    while (currentDate <= endDate) {
      const dateKey = currentDate.toISOString().split('T')[0];
      const dayEntries = entryMap.get(dateKey) || [];
      const count = dayEntries.length;
      
      // Calculate intensity level (0-4)
      let level = 0;
      if (count > 0) {
        if (count === 1) level = 1;
        else if (count === 2) level = 2;
        else if (count <= 4) level = 3;
        else level = 4;
      }
      
      days.push({
        date: dateKey,
        count,
        level,
        entries: dayEntries
      });
      
      currentDate.setDate(currentDate.getDate() + 1);
    }
    
    return days;
  };

  const calendarData = generateCalendarData();
  const maxCount = Math.max(...calendarData.map(d => d.count));
  
  // Get color for intensity level
  const getColor = (level: number): string => {
    const colors = {
      0: '#f3f4f6', // No entries
      1: '#dcfce7', // 1 entry
      2: '#bbf7d0', // 2 entries
      3: '#86efac', // 3-4 entries
      4: '#22c55e'  // 5+ entries
    };
    return colors[level as keyof typeof colors] || colors[0];
  };

  const handleDayClick = (day: DayData) => {
    setSelectedDay(day);
    if (day.count > 0) {
      setFilters({ dateRange: { start: new Date(day.date), end: new Date(day.date) } });
    }
  };

  const clearSelection = () => {
    setSelectedDay(null);
    setFilters({ dateRange: null });
  };

  // Group days by weeks
  const groupByWeeks = (days: DayData[]) => {
    const weeks: DayData[][] = [];
    let currentWeek: DayData[] = [];
    
    days.forEach((day, index) => {
      const dayOfWeek = new Date(day.date).getDay();
      
      // Start new week on Sunday
      if (dayOfWeek === 0 && currentWeek.length > 0) {
        weeks.push(currentWeek);
        currentWeek = [];
      }
      
      currentWeek.push(day);
      
      // Push last week
      if (index === days.length - 1) {
        weeks.push(currentWeek);
      }
    });
    
    return weeks;
  };

  const weeks = groupByWeeks(calendarData);
  const weekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  return (
    <div className="bg-white rounded-lg shadow-sm border border-warm-gray-200 p-6">
      <div className="flex items-center justify-between mb-4">
        <h3 className="text-lg font-semibold text-warm-gray-800">
          Writing Activity Heatmap
        </h3>
        {selectedDay && (
          <button
            onClick={clearSelection}
            className="text-xs bg-blue-100 text-blue-700 px-2 py-1 rounded hover:bg-blue-200 transition-colors"
          >
            Clear Selection
          </button>
        )}
      </div>

      {selectedDay && (
        <div className="mb-4 p-3 bg-green-50 rounded-lg">
          <div className="flex items-center justify-between">
            <div>
              <span className="text-sm font-medium text-green-800">
                {new Date(selectedDay.date).toLocaleDateString('en-US', { 
                  weekday: 'long', 
                  year: 'numeric', 
                  month: 'long', 
                  day: 'numeric' 
                })}
              </span>
              <p className="text-xs text-green-600 mt-1">
                {selectedDay.count} {selectedDay.count === 1 ? 'entry' : 'entries'}
              </p>
            </div>
            <button
              onClick={clearSelection}
              className="text-xs text-green-600 hover:text-green-800 underline"
            >
              Clear
            </button>
          </div>
        </div>
      )}

      <div className="overflow-x-auto">
        <div className="inline-block min-w-full">
          {/* Month labels */}
          <div className="flex mb-2">
            <div className="w-8"></div>
            {weeks.map((week, weekIndex) => {
              const firstDay = week[0];
              const date = new Date(firstDay.date);
              const isFirstWeekOfMonth = date.getDate() <= 7;
              
              return (
                <div key={weekIndex} className="w-3 text-xs text-center text-warm-gray-500">
                  {isFirstWeekOfMonth ? monthNames[date.getMonth()] : ''}
                </div>
              );
            })}
          </div>

          {/* Calendar grid */}
          <div className="flex">
            {/* Weekday labels */}
            <div className="flex flex-col mr-1">
              {weekdays.map((day, index) => (
                <div key={day} className="h-3 mb-1 text-xs text-warm-gray-500 flex items-center">
                  {index % 2 === 1 ? day.slice(0, 3) : ''}
                </div>
              ))}
            </div>

            {/* Calendar cells */}
            <div className="flex">
              {weeks.map((week, weekIndex) => (
                <div key={weekIndex} className="flex flex-col mr-1">
                  {Array.from({ length: 7 }, (_, dayIndex) => {
                    const day = week.find(d => new Date(d.date).getDay() === dayIndex);
                    
                    if (!day) {
                      return <div key={dayIndex} className="w-3 h-3 mb-1"></div>;
                    }
                    
                    const isSelected = selectedDay?.date === day.date;
                    const isHovered = hoveredDay?.date === day.date;
                    
                    return (
                      <div
                        key={day.date}
                        className={`w-3 h-3 mb-1 rounded-sm cursor-pointer transition-all duration-200 ${
                          isSelected ? 'ring-2 ring-blue-500 ring-offset-1' : ''
                        } ${
                          isHovered ? 'scale-110' : ''
                        }`}
                        style={{ backgroundColor: getColor(day.level) }}
                        onClick={() => handleDayClick(day)}
                        onMouseEnter={() => setHoveredDay(day)}
                        onMouseLeave={() => setHoveredDay(null)}
                        title={`${new Date(day.date).toLocaleDateString()}: ${day.count} entries`}
                      />
                    );
                  })}
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>

      {/* Legend */}
      <div className="flex items-center justify-between mt-4 text-xs text-warm-gray-500">
        <span>Less</span>
        <div className="flex items-center gap-1">
          {[0, 1, 2, 3, 4].map(level => (
            <div
              key={level}
              className="w-3 h-3 rounded-sm"
              style={{ backgroundColor: getColor(level) }}
              title={`${level === 0 ? 'No entries' : level === 4 ? '5+ entries' : `${level} ${level === 1 ? 'entry' : 'entries'}`}`}
            />
          ))}
        </div>
        <span>More</span>
      </div>

      {/* Tooltip */}
      {hoveredDay && (
        <div className="mt-2 p-2 bg-gray-50 rounded text-sm">
          <div className="font-medium">
            {new Date(hoveredDay.date).toLocaleDateString('en-US', { 
              weekday: 'short', 
              month: 'short', 
              day: 'numeric' 
            })}
          </div>
          <div className="text-warm-gray-600">
            {hoveredDay.count} {hoveredDay.count === 1 ? 'entry' : 'entries'}
            {hoveredDay.count > 0 && ' - Click to filter'}
          </div>
        </div>
      )}
    </div>
  );
};

export default HeatmapCalendar;